/**
 * 
 */
package net.sf.cldsql.sql2json.main;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.sf.cldsql.dj.container.base.DiBeanImpl;
import net.sf.cldsql.dj.mvc.DiRoute;
import net.sf.cldsql.dj.mvc.DiContext;
import net.sf.cldsql.dj.utl.DiException;

/**
 * ControllerService
 */
public class SjControllerImpl extends DiBeanImpl implements SjController {
    ArrayList<UrlServiceEntry> urlPtns = new ArrayList<UrlServiceEntry>(); 
    
    public void register(String requestMethod, String urlRegexp, String service) {
        register(requestMethod, urlRegexp, service, null);
    }
    
    /* (non-Javadoc)
     * @see net.sf.cldsql.dj.mvc.DiController#register(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
     */
    public void register(String requestMethod, String urlRegexp, String serviceName, String method) {
        if (!urlRegexp.startsWith("^")) {
            new DiException("Ambigous url pattern specified.");
        }
        urlPtns.add(new UrlServiceEntry(requestMethod, urlRegexp, serviceName, method));
    }

    /* (non-Javadoc) @see net.sf.cldsql.sql2json.main.SjController#find(java.lang.String, java.util.Map) */
    @SuppressWarnings("unused")
    public DiRoute find(DiContext context, String... args) {
        //DiContext context = (DiContext)args[0];
        String path = (String) context.getPathInfo();
        String requestMethod = (String) context.getMethod();
        Object[] serviceArgs;
        ArrayList<Object> argsList = new ArrayList<Object>();
        //argsList.add(args[0]);
        argsList.add(context);
        log.info("find route for request {} with args {}.", path, context != null ? context.getParameterMap() : null);
        for (int k = 0; k < urlPtns.size(); k ++) {
            UrlServiceEntry url = urlPtns.get(k);
            Pattern p = url.getUrlPattern();
            Matcher m = p.matcher(path);
            
            if (requestMethod.matches(url.getRequestMethod())) {
                for (int j = 0; m.find(); j ++) {
                    ArrayList<String> argsStrList = new ArrayList<String>();
                    for (int i = 1; i <= m.groupCount(); i ++) {
                        argsStrList.add(m.group(i));
                    }
                    String[] argsStrArr = new String[argsStrList.size()];
                    argsStrList.toArray(argsStrArr);
                    argsList.add(argsStrArr);
                    serviceArgs = argsList.toArray();
                    DiRoute route = new DiRoute(url.getService(), url.getMethod(), serviceArgs);
                    log.info("found route {}.", route);
                    return route;
                    
                }
            }
        }
        throw new DiException("Unknown url pattern " + path);
        /*
        // {table_name}/{id}?...
        if (path.matches("^/([^/]+)/([^/]+)/(GET|POST|PUT|DELETE)$")) {
            Pattern p = Pattern.compile("^/([^/]+)/([^/]+)/(GET|POST|PUT|DELETE)$");
            Matcher m = p.matcher(path);
            //ArrayList<Object> argsList = new ArrayList<Object>();
            argsList.add(args[0]);
            for (int j = 0; m.find(); j ++) {
                if (j >= 1) {
                    new DiException("Ambigous url pattern specified.");
                }
                for (int i = 0; i < m.groupCount(); i ++) {
                    argsList.add(m.group(i));
                }
            }
            String[] parts = path.split("/");
            serviceArgs = argsList.toArray();//new Object[] {args[0], parts[1], "id", parts[2]};
            context.setMethod(parts[2]);
        } else if (path.matches("^/([^/]+)/([^/]+)$")) {
            Pattern p = Pattern.compile("^/([^/]+)/([^/]+)$");
            Matcher m = p.matcher(path);
            //ArrayList<Object> argsList = new ArrayList<Object>();
            argsList.add(args[0]);
            for (int j = 0; m.find(); j ++) {
                if (j >= 1) {
                    new DiException("Ambigous url pattern specified.");
                }
                for (int i = 1; i <= m.groupCount(); i ++) {
                    argsList.add(m.group(i));
                }
            }
            String[] parts = path.split("/");
            serviceArgs = argsList.toArray();//new Object[] {args[0], parts[1], "id", parts[2]};
            context.setMethod(parts[2]);
            //String[] parts = path.split("/");
            //serviceArgs = new Object[] {args[0], parts[1], "id", parts[2]};
            
        } else if (path.matches("^/([^/]+)$")) {
            String[] parts = path.split("/");
            serviceArgs = new Object[] {args[0], parts[1]};
        } else {
            throw new DiException("unknown request path " + path);
        }
        
        String pkg = getClass().getPackage().getName();
        
        return new DiRoute(pkg + ".SjService", "execute", serviceArgs);
        */
        
        /*
        paramMap.put("select:*", new String[] {""});
        paramMap.put("from:" + tableName, new String[] {""});
        paramMap.put("where:" + idName + ":eq", new String[] {idValue});
        */
    }

}
